package com.quan.bookmall.service.impl;

import com.quan.bookmall.dto.BookDTO;
import com.quan.bookmall.dto.OrderDTO;
import com.quan.bookmall.dto.OrderItemDTO;
import com.quan.bookmall.dto.UserDTO;
import com.quan.bookmall.dto.request.OrderQueryRequest;
import com.quan.bookmall.dto.response.StatisticsResponse;
import com.quan.bookmall.entity.Book;
import com.quan.bookmall.entity.CartItem;
import com.quan.bookmall.entity.Order;
import com.quan.bookmall.entity.OrderItem;
import com.quan.bookmall.repository.BookRepository;
import com.quan.bookmall.repository.CartItemRepository;
import com.quan.bookmall.repository.OrderItemRepository;
import com.quan.bookmall.repository.OrderRepository;
import com.quan.bookmall.service.BookService;
import com.quan.bookmall.service.OrderService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.EntityNotFoundException;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class OrderServiceImpl implements OrderService {
    
    private final OrderRepository orderRepository;
    private final OrderItemRepository orderItemRepository;
    private final CartItemRepository cartItemRepository;
    private final BookRepository bookRepository;
    private final BookService bookService;
    
    @Override
    public OrderDTO findById(Long id) {
        Order order = orderRepository.findById(id)
                .orElseThrow(() -> new EntityNotFoundException("订单不存在"));
        return convertToDTO(order);
    }
    
    @Override
    public Page<OrderDTO> findByUserId(Long userId, Pageable pageable) {
        return orderRepository.findByUserId(userId, pageable).map(this::convertToDTO);
    }
    
    @Override
    public Page<OrderDTO> findByUserIdAndConditions(Long userId, OrderQueryRequest queryRequest) {
        Pageable pageable = PageRequest.of(
                queryRequest.getPage(),
                queryRequest.getSize(),
                Sort.by(Sort.Direction.DESC, "createTime")
        );
        
        return orderRepository.findByUserIdAndTimeRangeAndBookName(
                userId,
                queryRequest.getStartTime(),
                queryRequest.getEndTime(),
                queryRequest.getBookName(),
                pageable
        ).map(this::convertToDTO);
    }
    
    @Override
    public Page<OrderDTO> findByConditions(OrderQueryRequest queryRequest) {
        Pageable pageable = PageRequest.of(
                queryRequest.getPage(),
                queryRequest.getSize(),
                Sort.by(Sort.Direction.DESC, "createTime")
        );
        
        return orderRepository.findByTimeRangeAndBookName(
                queryRequest.getStartTime(),
                queryRequest.getEndTime(),
                queryRequest.getBookName(),
                pageable
        ).map(this::convertToDTO);
    }
    
    @Override
    @Transactional
    public OrderDTO createFromCart(Long userId) {
        List<CartItem> cartItems = cartItemRepository.findByUserId(userId);
        if (cartItems.isEmpty()) {
            throw new IllegalStateException("购物车为空");
        }
        
        // 创建订单
        Order order = new Order();
        order.setUserId(userId);
        order.setOrderNo(generateOrderNo());
        order.setStatus(1);
        
        BigDecimal totalAmount = BigDecimal.ZERO;
        List<OrderItem> orderItems = new ArrayList<>();
        
        // 创建订单项并计算总金额
        for (CartItem cartItem : cartItems) {
            Book book = bookRepository.findById(cartItem.getBookId())
                    .orElseThrow(() -> new EntityNotFoundException("书籍不存在"));
            
            // 检查库存
            if (book.getStock() < cartItem.getQuantity()) {
                throw new IllegalStateException("《" + book.getName() + "》库存不足");
            }
            
            // 减少库存
            bookService.updateStock(book.getId(), -cartItem.getQuantity());
            
            // 创建订单项
            OrderItem orderItem = new OrderItem();
            orderItem.setBookId(book.getId());
            orderItem.setBookName(book.getName());
            orderItem.setAuthor(book.getAuthor());
            orderItem.setIsbn(book.getIsbn());
            orderItem.setQuantity(cartItem.getQuantity());
            orderItem.setPrice(book.getPrice());
            orderItem.setSubtotal(book.getPrice().multiply(BigDecimal.valueOf(cartItem.getQuantity())));
            
            orderItems.add(orderItem);
            totalAmount = totalAmount.add(orderItem.getSubtotal());
        }
        
        order.setTotalAmount(totalAmount);
        Order savedOrder = orderRepository.save(order);
        
        // 保存订单项
        for (OrderItem orderItem : orderItems) {
            orderItem.setOrderId(savedOrder.getId());
            orderItemRepository.save(orderItem);
        }
        
        // 清空购物车
        cartItemRepository.deleteAll(cartItems);
        
        return convertToDTO(savedOrder);
    }
    
    @Override
    public StatisticsResponse getBookSalesStatistics(LocalDateTime startTime, LocalDateTime endTime) {
        List<Object[]> bookSalesData = orderItemRepository.findBookSalesStatistics(startTime, endTime);
        
        List<StatisticsResponse.BookSalesItem> bookSalesItems = bookSalesData.stream()
                .map(data -> new StatisticsResponse.BookSalesItem(
                        (String) data[0],
                        ((Number) data[1]).longValue()
                ))
                .collect(Collectors.toList());
        
        StatisticsResponse response = new StatisticsResponse();
        response.setBookSalesStatistics(bookSalesItems);
        return response;
    }
    
    @Override
    public StatisticsResponse getUserConsumptionStatistics(LocalDateTime startTime, LocalDateTime endTime) {
        List<Object[]> userConsumptionData = orderItemRepository.findUserConsumptionStatistics(startTime, endTime);
        
        List<StatisticsResponse.UserConsumptionItem> userConsumptionItems = userConsumptionData.stream()
                .map(data -> new StatisticsResponse.UserConsumptionItem(
                        ((Number) data[0]).longValue(),
                        (String) data[1],
                        (BigDecimal) data[2]
                ))
                .collect(Collectors.toList());
        
        StatisticsResponse response = new StatisticsResponse();
        response.setUserConsumptionStatistics(userConsumptionItems);
        return response;
    }
    
    @Override
    public StatisticsResponse getUserBookStatistics(Long userId, LocalDateTime startTime, LocalDateTime endTime) {
        List<OrderItem> orderItems = orderItemRepository.findByUserIdAndTimeRange(userId, startTime, endTime);
        
        List<StatisticsResponse.UserBookStatItem> userBookStatItems = orderItems.stream()
                .map(item -> new StatisticsResponse.UserBookStatItem(
                        item.getBookName(),
                        item.getQuantity(),
                        item.getPrice(),
                        item.getSubtotal()
                ))
                .collect(Collectors.toList());
        
        // 计算订单总数（根据不同的订单ID）
        Integer totalOrders = (int) orderItems.stream()
                .map(OrderItem::getOrderId)
                .distinct()
                .count();
        
        // 计算总书籍数量和总金额
        Integer totalBooks = orderItems.stream()
                .mapToInt(OrderItem::getQuantity)
                .sum();
        
        BigDecimal totalAmount = orderItems.stream()
                .map(OrderItem::getSubtotal)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        
        StatisticsResponse response = new StatisticsResponse();
        response.setUserBookStatistics(userBookStatItems);
        response.setTotalOrders(totalOrders);
        response.setTotalBooks(totalBooks);
        response.setTotalAmount(totalAmount);
        return response;
    }
    
    private OrderDTO convertToDTO(Order order) {
        OrderDTO orderDTO = new OrderDTO();
        BeanUtils.copyProperties(order, orderDTO);
        
        // 获取订单项
        List<OrderItem> orderItems = orderItemRepository.findByOrderId(order.getId());
        List<OrderItemDTO> orderItemDTOs = orderItems.stream()
                .map(this::convertToOrderItemDTO)
                .collect(Collectors.toList());
        
        orderDTO.setOrderItems(orderItemDTOs);
        
        return orderDTO;
    }
    
    private OrderItemDTO convertToOrderItemDTO(OrderItem orderItem) {
        OrderItemDTO orderItemDTO = new OrderItemDTO();
        BeanUtils.copyProperties(orderItem, orderItemDTO);
        
        if (orderItem.getBook() != null) {
            BookDTO bookDTO = new BookDTO();
            BeanUtils.copyProperties(orderItem.getBook(), bookDTO);
            orderItemDTO.setBook(bookDTO);
        }
        
        return orderItemDTO;
    }
    
    private String generateOrderNo() {
        // 生成订单编号：ORD + 年月日 + 6位随机数
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        String dateStr = LocalDateTime.now().format(formatter);
        int random = (int) (Math.random() * 900000) + 100000;
        return "ORD" + dateStr + random;
    }
} 